<template>
  <a-modal
    :width="800"
    :visible="props.multipleDialog"
    :title="title"
    :destroyOnClose="true"
    @ok="submitDialog"
    @cancel="closeDialog"
    :okText="t('确认')"
    :cancelText="t('取消')"
    :bodyStyle="{ padding: '20px' }"
  >
    <a-row :gutter="12" style="margin-bottom: 10px">
      <a-col :span="8">
        <a-input v-model:value="state.searchText" :placeholder="t('请输入要查询的关键字')" />
      </a-col>
      <a-col>
        <a-button type="primary" @click="getDatasourceList(1)">
          <template #icon><Icon icon="ant-design:search-outlined" /></template>
          {{ t('搜索') }}
        </a-button>
      </a-col>
      <a-col>
        <a-button @click="resetSearch">
          <template #icon><Icon icon="ant-design:sync-outlined" /></template>
          {{ t('重置') }}
        </a-button>
      </a-col>
    </a-row>
    <a-tabs
      v-model:activeKey="state.activeKey"
      v-if="popupType === 'multiple' || popupType === 'preload'"
    >
      <a-tab-pane key="1" :tab="t('数据选择')" style="overflow-y: auto">
        <a-table
          :dataSource="state.dataSourceList"
          :columns="state.sourceColumns"
          :row-selection="{
            selectedRowKeys: state.selectedRowKeys,
            onChange: onSelectChange,
          }"
          :pagination="paginationProps"
          :scroll="{ y: '200px' }"
        />
      </a-tab-pane>
      <a-tab-pane key="2" :tab="t('已选记录')" force-render>
        <a-table
          :dataSource="selectedList"
          :columns="state.selectedColumns"
          :scroll="{ y: '200px' }"
        >
          <template #bodyCell="{ column, record, index }">
            <template v-if="column.key === 'delete'">
              <Icon
                icon="ant-design:delete-outlined"
                color="#f56c6c"
                @click="deleteSelected(record, index)"
                style="cursor: pointer"
              />
            </template>
          </template>
        </a-table>
      </a-tab-pane>
    </a-tabs>
    <a-table
      v-else-if="popupType === 'associate'"
      :dataSource="state.dataSourceList"
      :columns="state.sourceColumns"
      :pagination="paginationProps"
      :row-selection="{
        selectedRowKeys: state.selectedRowKeys,
        onChange: onSelectChange,
        type: 'radio',
      }"
      :scroll="{ y: '200px' }"
    />
  </a-modal>
</template>

<script lang="ts" setup>
  import { onMounted, watch, reactive, computed, inject, ref } from 'vue';
  import { cloneDeep } from 'lodash-es';
  import { Icon } from '/@/components/Icon';
  import { getDatasourceById } from '/@/api/system/datasource';
  import { getDicDetailPageList } from '/@/api/system/dic';
  import { isFunction } from '/@/utils/is';
  import type { ColumnProps } from 'ant-design-vue/lib/table';
  import { camelCaseString, apiConfigFunc } from '/@/utils/event/design';
  import { useI18n } from '/@/hooks/web/useI18n';
  const { t } = useI18n();
  const props = defineProps({
    multipleDialog: { type: Boolean },
    popupType: { type: String },
    dataSourceOptions: { type: Array },
    params: {
      type: [Array, Object, String, Number],
    },
    value: {
      type: String,
    },
    popupValue: { type: String },
    labelField: { type: String },
    valueField: { type: String },
    selectedDataSource: {
      type: Array as PropType<any[]>,
      default: () => [],
    },
    dicOptions: { type: Array as PropType<any[]> },
    //数据来源 默认为空  如果不为空
    datasourceType: String,
    apiConfig: Object,
    //是否子表按钮选数据使用
    isSubFormUse: {
      type: Boolean,
      default: false,
    },
    mainKey: String,
    subTableIndex: Number,
  });
  const emit = defineEmits([
    'update:multipleDialog',
    'update:popupValue',
    'update:selectedDataSource',
    'getList',
    'submit',
  ]);

  onMounted(async () => {
    if (props.isSubFormUse) {
      await getDatasourceList(1);
    }
  });

  const state = reactive({
    selectedRowKeys: [] as any[],
    activeKey: '1',
    searchText: '',
    sourceColumns: [] as ColumnProps[],
    selectedColumns: [] as ColumnProps[],
    dataSourceList: [] as any[],
    assoComponent: {},
  });

  const selectedList = ref(props.selectedDataSource);

  const paginationProps = reactive({
    current: 1,
    total: 0,
    pageSize: 10,
    onChange: (page) => getDatasourceList(page),
  });
  const formModel = inject<any>('formModel', null);
  const isCustomForm = inject<boolean>('isCustomForm', false);
  const title = computed(() => {
    switch (props.popupType) {
      case 'multiple':
        return t('多选弹层-选择记录');
      case 'associate':
        return t('联想弹层-联想数据配置');
      case 'preload':
        return t('选择数据');
      default:
        return '';
    }
  });

  watch(
    () => props.datasourceType,
    (val) => {
      let options = [] as any[];
      if (val === 'datasource' && props.dataSourceOptions?.length) {
        options = props.dataSourceOptions as any[];
      }
      if (val === 'dic' && props.dicOptions?.length) {
        options = props.dicOptions as any[];
      }
      if (val === 'api') {
        options = props.apiConfig?.outputParams as any[];
      }
      options?.map((item: any) => {
        if (item.show || !Object.keys(item).includes('show')) {
          state.sourceColumns.push({
            title: item.tableTitle,
            dataIndex: item.name,
            align: 'center',
            width: Number(item.width),
          });
        }
      });
      state.selectedColumns = cloneDeep(state.sourceColumns);
      state.selectedColumns.unshift({
        align: 'center',
        title: '',
        dataIndex: 'delete',
        key: 'delete',
        width: 50,
      });
    },
    {
      deep: true,
      immediate: true,
    },
  );

  watch(
    () => [state.dataSourceList, props.selectedDataSource, props.value],
    () => {
      emit('getList', state.dataSourceList);
      if (!state.dataSourceList.length) return;
      selectedList.value = [];
      state.selectedRowKeys = [];
      state.dataSourceList.map((data: any, index: number) => {
        data.key = index + 1;
        if (props.value) {
          props.selectedDataSource.map((select: any) => {
            if (data.key === select.key) {
              selectedList.value.push(data);
              state.selectedRowKeys.push(data.key);
            }
          });
        }
      });
    },
    {
      deep: true,
    },
  );

  const resetSearch = () => {
    state.searchText = '';
    getDatasourceList(1);
  };
  const closeDialog = () => {
    emit('update:multipleDialog', false);
  };

  const submitDialog = () => {
    let saveValueArr: string[] = [];
    let showValueArr: string[] = [];
    let saveValue = '';
    let showValue = '';
    selectedList.value?.map((item: any) => {
      saveValueArr.push(item[props.valueField!]);
      showValueArr.push(item[props.labelField!]);
    });
    //value相同去重
    saveValue = [...new Set(saveValueArr)].join(',');
    showValue = showValueArr.join(',');

    setFormModel();

    emit('update:multipleDialog', false);
    emit('update:popupValue', showValue);
    emit('update:selectedDataSource', selectedList.value);
    emit('submit', props.isSubFormUse ? selectedList.value : saveValue);
  };

  const setFormModel = (isNull?) => {
    if (props.popupType === 'associate') {
      let assoConfig;
      switch (props.datasourceType) {
        case 'datasource':
          assoConfig = props.dataSourceOptions;
          break;
        case 'dic':
          assoConfig = props.dicOptions;
          break;
        case 'api':
          assoConfig = props.apiConfig?.outputParams;
          break;
      }
      if (!formModel) return;
      assoConfig?.map((item: any) => {
        if (item.bindField) {
          const value = selectedList.value.length ? selectedList.value![0][item.name] : '';
          if (isCustomForm) {
            if (props.mainKey) {
              formModel[props.mainKey][props.subTableIndex!][item.bindField!] = isNull ? '' : value;
            } else {
              formModel[item.bindField!] = isNull ? '' : value;
            }
          } else {
            if (props.mainKey) {
              formModel[props.mainKey][props.subTableIndex!][camelCaseString(item.bindField)!] =
                isNull ? '' : value;
            } else {
              formModel[camelCaseString(item.bindField)!] = isNull ? '' : value;
            }
          }
        }
      });
    }
  };

  const getDatasourceList = async (limit = 1) => {
    paginationProps.current = limit;
    let api;
    if (props.datasourceType) {
      if (props.datasourceType === 'dic') {
        api = getDicDetailPageList;
      }
      if (props.datasourceType === 'datasource') {
        api = getDatasourceById;
      }
      if (props.datasourceType === 'api') {
        state.dataSourceList = await apiConfigFunc(props.apiConfig, isCustomForm, formModel);
      }
    }
    if (!api || !isFunction(api)) return;
    state.dataSourceList = [];
    try {
      let dataParams = {};
      const pageParams = { order: 'desc', size: 10, limit, keyword: state.searchText };
      if (props.datasourceType === 'dic') {
        Object.assign(dataParams, props.params, pageParams);
      }
      if (props.datasourceType === 'datasource') {
        Object.assign(
          dataParams,
          {
            id: props.params as string,
          },
          pageParams,
        );
      }
      const res = await api(dataParams);
      state.dataSourceList = res.list;
      paginationProps.total = Number(res.total);
    } catch (error) {
      console.warn(error);
    }
  };

  const onSelectChange = (rowKeys, selectedRows) => {
    state.selectedRowKeys = rowKeys;
    selectedList.value = selectedRows;
  };

  const deleteSelected = (record, index) => {
    selectedList.value.splice(index, 1);
    state.selectedRowKeys = state.selectedRowKeys.filter((item) => {
      return item !== record.key;
    });
  };
  defineExpose({ getDatasourceList, setFormModel });
</script>

<style scoped lang="less"></style>
